home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 12
/
Mac Magazin and MacEasy Magazine CD - Issue 12.iso
/
Sharewarebibliothek
/
Anwendungen
/
Wissenschaft & Technik
/
Finder Marquee ƒ
/
test_app.c
< prev
Wrap
C/C++ Source or Header
|
1995-07-10
|
5KB
|
190 lines
/*
Finder Marquee
by Jordan Zimmerman
(c)1995 by Altura Software, Inc.
Unlimited use is hereby granted without restriction. However,
the author would appreciate credit if possible. Please send
comments, questions, bugs, etc. to jordanz@altura.com
This code implements a "rubber band" marquee select rect
with very smooth drawing in a manner similar to the Mac Finder.
*/
#include "finder_marquee.h"
static void do_marquee(Point local_pt);
static void draw_highlights(void);
static int selections_proc(finder_marquee_rec* marquee_ptr);
static void change_selection_proc(finder_marquee_rec* marquee_ptr, const Rect* old_marquee_r_ptr);
// some simple objects to demonstrate highlighting
typedef struct
{
Rect bounds_r;
int selected_flag;
} highlight_rec;
highlight_rec highlights_tab[] =
{
{ {10, 10, 42, 42}, false },
{ {50, 75, 82, 107}, false },
{ {100, 10, 132, 42}, false },
{ {110, 200, 142, 232}, false }
};
// very generic Mac event loop
void main(void)
{
Rect bounds_r;
WindowPtr window_ptr;
int is_done = false;
MaxApplZone();
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(NULL);
InitCursor();
InsertMenu(NewMenu(1, "\pFinder Marquee by Jordan Zimmerman"), 0);
DrawMenuBar();
SetRect(&bounds_r, 50, 50, 300, 250);
SetPort(window_ptr = NewCWindow(NULL, &bounds_r, "\pPress Any Key To Quit", true, noGrowDocProc, (WindowPtr)-1, false, 0));
while ( !is_done )
{
EventRecord the_event;
WaitNextEvent(everyEvent, &the_event, GetDblTime(), NULL);
switch ( the_event.what )
{
case keyDown:
case autoKey:
is_done = true;
break;
case updateEvt:
BeginUpdate(window_ptr);
draw_highlights();
EndUpdate(window_ptr);
break;
case mouseDown:
GlobalToLocal(&the_event.where);
do_marquee(the_event.where);
break;
}
}
} // main
// here's the meat of the program
// while this example does it all in one function,
// you could just as easily separate the various calls and do it in the background
static void do_marquee(Point local_pt)
{
finder_marquee_rec marquee;
// the following are necessary only if you want to do your selection
// while the marquee is being dragged ala the Finder.
// Set these to NULL if you don't want that functionality
marquee.selections_proc = selections_proc;
marquee.change_selection_proc = change_selection_proc;
// start our marquee session
FinderMarqueeBegin(&marquee, local_pt);
while ( StillDown() )
{
Point new_pt;
long dummy;
GetMouse(&new_pt);
// do the next point
FinderMarqueeContinue(&marquee, new_pt);
// a little delay makes things look smoother
Delay(1, &dummy);
}
// finish our marquee session
FinderMarqueeEnd(&marquee);
} // do_marquee
// walk through our highlight rects and see if any of the selections will change.
// the marquee drawing must work slightly differently if there's going to be
// a selection change.
// If there's no selection change, the marquee can be drawn in one step (PaintRgn)
// that will erase the old and draw the new. If there is a selection, though, the
// old marquee must be erased, the selections must be drawn, and then the new marquee
// can be drawn.
static int selections_proc(finder_marquee_rec* marquee_ptr)
{
int i;
int qty = sizeof(highlights_tab) / sizeof(*highlights_tab);
highlight_rec* tab_ptr = highlights_tab;
for ( i = 0; i < qty; ++i, ++tab_ptr )
{
Rect sect_r;
if ( SectRect(&marquee_ptr->marquee_r, &tab_ptr->bounds_r, §_r) != tab_ptr->selected_flag )
{
return true;
}
}
return false;
} // selections_proc
// invert any of the highlight rects that intersect the current marquee rect
static void change_selection_proc(finder_marquee_rec* marquee_ptr, const Rect* old_marquee_r_ptr)
{
int i;
int qty = sizeof(highlights_tab) / sizeof(*highlights_tab);
highlight_rec* tab_ptr = highlights_tab;
for ( i = 0; i < qty; ++i, ++tab_ptr )
{
Rect sect_r;
if ( SectRect(&marquee_ptr->marquee_r, &tab_ptr->bounds_r, §_r) != tab_ptr->selected_flag )
{
tab_ptr->selected_flag = !tab_ptr->selected_flag;
InvertRect(&tab_ptr->bounds_r);
}
}
} // change_selection_proc
// draw in response to an update event
static void draw_highlights(void)
{
int i;
int qty = sizeof(highlights_tab) / sizeof(*highlights_tab);
highlight_rec* tab_ptr = highlights_tab;
for ( i = 0; i < qty; ++i, ++tab_ptr )
{
FrameRect(&tab_ptr->bounds_r);
if ( tab_ptr->selected_flag )
{
InvertRect(&tab_ptr->bounds_r);
}
}
} // draw_highlights